import mountElement from './mountElement'
import createDOMElement from './createDOMElement'
import diffComponent from './diffComponent'
import updateElementNode from './updateElementNode'
import updateTextNode from './updateTextNode'
import unmountNode from './unmountNode'

export default function diff(virtualDOM, container, oldDOM) {
    const oldVirtualDOM = oldDOM && oldDOM._virtualDOM
    const oldComponent = oldVirtualDOM && oldVirtualDOM.component
    if(!oldDOM) {
        mountElement(virtualDOM, container)
        return
    }

    // 新旧 virtualDOM 节点类型不同，且不是组件
    if(virtualDOM.type !== oldVirtualDOM.type && typeof virtualDOM.type !== 'function') {
        // 使用新的 virtualDOM 生成真实的 DOM, 替换旧的 DOM
        const newElement = createDOMElement(virtualDOM)
        oldDOM.parentNode.replaceChild(newElement, oldDOM)
        return
    }

    // 组件
    if(typeof virtualDOM.type === 'function') {
        diffComponent(virtualDOM, oldComponent, oldDOM, container)
        return
    }

    // 新旧 virtualDOM 节点类型相同
    if(oldVirtualDOM && oldVirtualDOM.type === virtualDOM.type) {
        if(virtualDOM.type === 'text') {
            // 如果是文本，更新内容
            updateTextNode(virtualDOM, oldVirtualDOM, oldDOM)
        }else{
            // 如果是元素，更新元素节点属性
            updateElementNode(oldDOM, virtualDOM, oldVirtualDOM)
        }

        let keyedElements = {}
        oldDOM.childNodes.forEach(child => {
            if(child.nodeType === 1) {
                const key = child.getAttribute('key') // 没有key属性，返回null
                console.log("diff -> key", key)
                if(key) {
                    keyedElements[key] = child
                }
            }
        })

        let hasNoKey = Object.keys(keyedElements).length === 0

        if(hasNoKey) {
            // 对比子节点
            virtualDOM.children.forEach((child, i) => {
                diff(child, oldDOM, oldDOM.childNodes[i])
            })
        }else{
            virtualDOM.children.forEach((child, i) => {
                let keyDom = keyedElements[child.props.key]
                console.log("diff -> keyDom", keyDom)
                if(keyDom) {
                    // 如果当前位置的元素，不是期望元素，就插入到当前位置元素前面，实现替换
                    if(oldDOM.childNodes[i] && oldDOM.childNodes[i] !== keyDom) {
                        oldDOM.insertBefore(keyDom, oldDOM.childNodes[i])
                    }
                }else{
                    mountElement(child, oldDOM, oldDOM.childNodes[i])
                }
            })
        }


        // 删除节点
        let oldChildNodes = oldDOM.childNodes
        if(oldChildNodes.length > virtualDOM.children.length) {
            if(hasNoKey) {
                for(let i = oldChildNodes.length - 1; i > virtualDOM.children.length - 1; i--) {
                    unmountNode(oldChildNodes[i])
                }
            }else{
                // 通过 key 删除节点
                for(let i = 0; i < oldChildNodes.length; i++) {
                    const oldChild = oldChildNodes[i]
                    const oldKey = oldChild._virtualDOM.props.key
                    const found = virtualDOM.children.some(i => i.props.key === oldKey)
                    if(!found) {
                        unmountNode(oldChild)
                    }
                }
            }
        }
    }
}